﻿Imports Business
Imports DTO


Public Class frmCompanyDepartment

    Dim bsOrganization As BSOrganization

    ''' <summary>
    ''' datatable organization
    ''' </summary>
    ''' <remarks></remarks>
    Dim dtOrgan As DataTable

    Dim dtLevel As DataTable

    Dim serverName As String

    Public Sub New(ByVal strServer As String)

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        Me.serverName = strServer

        bsOrganization = New BSOrganization(strServer)

        ' get datatable all organization
        dtOrgan = bsOrganization.GetOrganization()

        ' create datatable level 
        dtLevel = New DataTable()
        dtLevel.Columns.Add("KEY")
        dtLevel.Columns.Add("VALUE")

        dtLevel.Rows.Add("1", "Department")
        dtLevel.Rows.Add("0", "Company")


        ' fill combobox level
        Functions.FillComboBox(cboOrLevel, dtLevel)

    End Sub


    Private Sub frmCompanyDepartment_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

        LoadTreeOrgan(dtOrgan, trvOrgan)

        trvOrgan.ExpandAll()

        Functions.FillComboBox(cboGroup, New BSGroup(Me.serverName).GetAllGroup())
        Functions.FillComboBox(cboBeTo, bsOrganization.GetOrganization())

    End Sub


    ''' <summary>
    ''' Load tree view organization
    ''' </summary>
    ''' <remarks></remarks>
    Shared Sub LoadTreeOrgan(ByVal dtOrgan As DataTable, ByVal trvOrgan As TreeView)

        ' clear all nodes
        trvOrgan.Nodes.Clear()

        ' get company node
        For Each row As DataRow In dtOrgan.Rows

            If IsDBNull(row.Item("SUP_ORGANIZATIONAL_NO")) Then

                Dim node As TreeNode = New TreeNode()

                'set node text 
                node.Text = row.Item("ORGANIZATIONAL_NAME")

                'set node key
                node.Name = row.Item("ORGANIZATIONAL_NO")

                ' add root node
                trvOrgan.Nodes.Add(node)

                ' remove node is checked
                'dtOrgan.Rows.Remove(row)

                GetChildNodes(node.Name, dtOrgan, node)

            End If

        Next

    End Sub


    Shared Sub GetChildNodes(ByVal supNodeKey As String, ByVal dtNode As DataTable, ByVal supNode As TreeNode)

        For Each row As DataRow In dtNode.Rows

            If row.Item("SUP_ORGANIZATIONAL_NO").ToString().Equals(supNodeKey) Then

                Dim node As TreeNode = New TreeNode()

                'set node text 
                node.Text = row.Item("ORGANIZATIONAL_NAME")

                'set node key
                node.Name = row.Item("ORGANIZATIONAL_NO")

                'add child node to parent node
                supNode.Nodes.Add(node)

                ' get child nodes
                GetChildNodes(node.Name, dtNode, node)

            End If

        Next

    End Sub


    Private Sub disableActions()

        'disable details, disallowed actions 
        txtOrNo.ReadOnly = True
        txtOrName.ReadOnly = True
        txtNote.ReadOnly = True
        txtAddress.ReadOnly = True

        cboOrLevel.Enabled = False
        cboBeTo.Enabled = False
        cboGroup.Enabled = False

        btnAdd.Enabled = False
        btnModify.Enabled = False
        btnDelete.Enabled = False


    End Sub

    Private Sub enableActionAdd()

        ' clear all details and enable 
        txtOrNo.Text = Nothing
        txtOrNo.ReadOnly = False

        txtOrName.Text = Nothing
        txtOrName.ReadOnly = False

        cboOrLevel.Enabled = True
        cboOrLevel.SelectedValue = 1

        cboGroup.Enabled = True
        cboGroup.SelectedIndex = 0

        cboBeTo.Enabled = True
        cboBeTo.SelectedIndex = 0

        txtAddress.Text = Nothing
        txtAddress.ReadOnly = False

        txtNote.Text = Nothing
        txtNote.ReadOnly = False

        btnAdd.Enabled = True
        btnDelete.Enabled = True
        btnModify.Enabled = False
        btnDelete.Enabled = False

    End Sub

    Private Sub LoadDetails(ByVal node As TreeNode)

        For Each row As DataRow In dtOrgan.Rows

            If row.Item("ORGANIZATIONAL_NO").ToString().Equals(node.Name) Then

                'set no
                txtOrNo.Text = node.Name

                'set name
                txtOrName.Text = node.Text

                'set super dept
                If IsDBNull(row.Item("SUP_ORGANIZATIONAL_NO")) Then

                    ' set super dept = nothing
                    'txtBeTo.Text = Nothing
                    cboBeTo.Text = Nothing

                Else

                    '' set super dept
                    'For Each r As DataRow In dtOrgan.Rows

                    '    If r.Item("ORGANIZATIONAL_NO").ToString().Equals(row.Item("SUP_ORGANIZATIONAL_NO")) Then

                    '        txtBeTo.Text = r.Item("ORGANIZATIONAL_NAME").ToString()

                    '        Exit For

                    '    End If

                    'Next

                    cboBeTo.SelectedValue = row.Item("SUP_ORGANIZATIONAL_NO")


                End If

                ' set group ID
                If IsDBNull(row.Item("GROUP_ID")) Then

                    'set group = nothing
                    cboGroup.Text = Nothing

                    '' disable cbo group
                    'cboGroup.Enabled = False

                Else

                    '' enable cbo group
                    'cboGroup.Enabled = True

                    'set group name
                    cboGroup.SelectedValue = row.Item("GROUP_ID")

                End If


                ' it's a company 
                cboOrLevel.SelectedValue = row.Item("ORGANIZATIONAL_LEVEL")



                'set address
                If Not IsDBNull(row.Item("ADDRESS")) Then

                    'set address
                    txtAddress.Text = row.Item("ADDRESS").ToString()

                Else

                    txtAddress.Text = Nothing

                End If

                ' set note
                If Not IsDBNull(row.Item("NOTE")) Then

                    'set note
                    txtNote.Text = row.Item("NOTE")

                Else

                    txtNote.Text = Nothing

                End If

            End If

        Next

    End Sub


    Private Sub trvOrgan_AfterSelect(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles trvOrgan.AfterSelect

        ' disable action
        disableActions()

        'load details
        LoadDetails(e.Node)


    End Sub



    Private Sub trvOrgan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles trvOrgan.Click

    End Sub

    ' Dim m_OldSelectNode As TreeNode

    Private Sub trvOrgan_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles trvOrgan.MouseUp

        ' Show menu only if Right Mouse button is clicked
        If e.Button = MouseButtons.Right Then

            ' Point where mouse is clicked
            Dim p As Point = New Point(e.X, e.Y)

            ' Go to the node that the user clicked
            Dim node As TreeNode = trvOrgan.GetNodeAt(p)

            If Not node Is Nothing Then

                ' Highlight the node that the user clicked.
                trvOrgan.SelectedNode = node

                ' show menu
                mnuTreeview.Show(trvOrgan, p)

            End If

        End If

    End Sub

    Private Sub cboOrLevel_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)

        'If cboOrLevel.SelectedValue.ToString().Equals("0") Then

        '    ' clear group and disable
        '    cboGroup.Text = Nothing
        '    cboGroup.Enabled = False

        '    ' clear belong to and disable
        '    cboBeTo.Text = Nothing
        '    cboBeTo.Enabled = False

        'ElseIf cboOrLevel.SelectedValue.ToString().Equals("1") Then

        '    cboGroup.Enabled = True

        '    cboBeTo.Enabled = True

        'End If

    End Sub

    Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click

        ' clear all details and enable 
        enableActionAdd()


    End Sub



    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click

        frmMain.RemoveTabpage()

    End Sub


    ''' <summary>
    ''' menu add new organizational unit
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub mnuNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuNew.Click

        ' enable details + button add
        enableActionAdd()

        ' set belongs to
        cboBeTo.SelectedValue = trvOrgan.SelectedNode.Name

        ' set group
        For Each row As DataRow In dtOrgan.Rows

            If row.Item("ORGANIZATIONAL_NO").ToString().Equals(trvOrgan.SelectedNode.Name) Then

                If Not String.IsNullOrEmpty(row.Item("GROUP_ID").ToString()) Then

                    cboGroup.SelectedValue = row.Item("GROUP_ID").ToString()

                End If

            End If

        Next

    End Sub



    ''' <summary>
    '''  menu edit organizational unit 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub mnuEdit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuEdit.Click

        ' enable details + button modify and add
        LoadDetails(trvOrgan.SelectedNode)

        txtOrNo.ReadOnly = True

        txtOrName.ReadOnly = False

        txtAddress.ReadOnly = False

        txtNote.ReadOnly = False

        cboBeTo.Enabled = True

        cboGroup.Enabled = True

        cboOrLevel.Enabled = True

        btnModify.Enabled = True

        btnDelete.Enabled = True

        btnAdd.Enabled = False


    End Sub


    Dim strErr1 As String = "Organizational No cannot be empty."
    Dim strErr2 As String = "Organizational No has existed."
    Dim strErr3 As String = "Organizational Name cannot be empty."
    Dim strErr4 As String = "Department must have a parent."
    Dim strErr5 As String = "Group cannot be empty."
    Dim strErr6 As String = "Level cannot be empty."
    Dim strErr7 As String = "'Belongs to' cannot be itself or it child."
    Dim strErr8 As String = "Add organization have error."
    Dim strErr9 As String = "Update organization have an error."
    Dim strErr10 As String = "Delete organization have an error."
    Dim strErr11 As String = "Organization child must have same group as parent."

    Dim strMsg1 As String = "Add organization succeeded."
    Dim strMsg2 As String = "Update organization succeeded."
    Dim strMsg3 As String = "Delete organization succeeded."

    ''' <summary>
    ''' button Add new organizational unit
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAdd.Click

        ' flag = true if valid
        Dim flag As Boolean = True

        ' validate input data

        ' check if "no" not empty
        If Not String.IsNullOrEmpty(txtOrNo.Text) Then

            ' check if no is duplicated
            If Not CheckDuplicateNo(txtOrNo.Text) Then

                ' check if "name" not empty
                If Not String.IsNullOrEmpty(txtOrName.Text) Then

                    ' check level
                    If cboOrLevel.SelectedIndex > 0 Then

                        If cboOrLevel.SelectedValue.ToString().Equals("1") Then

                            ' check if "belongs to" not selected
                            If cboBeTo.SelectedIndex > 0 Then

                                ' check if group not empty
                                If cboGroup.SelectedIndex > 0 Then

                                    ' check group is valid
                                    If CheckGroup(cboGroup.SelectedValue.ToString(), cboBeTo.SelectedValue.ToString()) Then

                                        'clear message
                                        lblMessage.Text = Nothing

                                    Else

                                        ' print error message
                                        lblMessage.Text = strErr11

                                        'set flag
                                        flag = False

                                    End If


                                Else

                                    ' print message group not empty
                                    lblMessage.Text = strErr5

                                    ' set flag
                                    flag = False

                                End If

                            Else

                                'print message belongs to not empty
                                lblMessage.Text = strErr4

                                'set flag
                                flag = False

                            End If

                        Else

                            'clear message
                            lblMessage.Text = Nothing

                        End If

                    Else

                        ' print message level is not empty
                        lblMessage.Text = strErr6

                        ' set flag
                        flag = False

                    End If

                Else

                    ' print message name is not empty
                    lblMessage.Text = strErr3

                    'set flag
                    flag = False

                    txtOrName.Focus()

                End If

            Else

                ' print message no is duplicated
                lblMessage.Text = strErr2

                ' set flag = false
                flag = False

                txtOrNo.Focus()

            End If

        Else

            ' print message no is not empty
            lblMessage.Text = strErr1

            ' set flag = false
            flag = False

            txtOrNo.Focus()

        End If


        ' check if information about dto is valid
        If flag Then

            ' create dto organization
            Dim dtoOrganization As DTO.DTOOrganization = New DTOOrganization()

            'get inputs data 
            dtoOrganization.NoProperty = txtOrNo.Text

            dtoOrganization.NameProperty = txtOrName.Text

            dtoOrganization.LevelProperty = cboOrLevel.SelectedValue

            dtoOrganization.SupProperty = cboBeTo.SelectedValue.ToString()

            dtoOrganization.GroupProperty = cboGroup.SelectedValue.ToString()

            dtoOrganization.AddressProperty = txtAddress.Text

            dtoOrganization.NoteProperty = txtNote.Text

            ' add to database
            If bsOrganization.AddOrganization(dtoOrganization) Then

                ' print message
                lblMessage.Text = strMsg1

                ' load dtorgan and treeview
                dtOrgan = bsOrganization.GetOrganization()

                LoadTreeOrgan(dtOrgan, trvOrgan)

                trvOrgan.ExpandAll()

                'load combobox belong to
                Functions.FillComboBox(cboBeTo, bsOrganization.GetOrganization())

                ' clear all
                enableActionAdd()

            Else

                ' print error message
                lblMessage.Text = strErr8

            End If

        End If


    End Sub


    Private Function CheckDuplicateNo(ByVal strNo As String) As Boolean

        For Each row As DataRow In dtOrgan.Rows

            If row.Item("ORGANIZATIONAL_NO").ToString().Equals(strNo) Then

                Return True

            End If

        Next

        Return False

    End Function

    ''' <summary>
    ''' button Modify organization
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub btnModify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModify.Click

        'validate input data
        Dim flag As Boolean = True

        'check if name cannot be empty
        If Not String.IsNullOrEmpty(txtOrName.Text) Then

            ' check level
            If cboOrLevel.SelectedIndex > 0 Then

                ' check if level = department
                If cboOrLevel.SelectedValue = 1 Then

                    ' check if belong to not selected
                    If cboBeTo.SelectedIndex > 0 Then

                        ' check belongs to is not itself and its child
                        If Not cboBeTo.SelectedValue.ToString().Equals(txtOrNo.Text) And Not isChild(txtOrNo.Text, cboBeTo.SelectedValue) Then

                            ' check group not empty
                            If cboGroup.SelectedIndex > 0 Then

                                ' check group is valid
                                If CheckGroup(cboGroup.SelectedValue.ToString(), cboBeTo.SelectedValue.ToString()) Then

                                    'clear message
                                    lblMessage.Text = Nothing

                                Else

                                    ' print error message
                                    lblMessage.Text = strErr11

                                    'set flag
                                    flag = False

                                End If

                            Else

                                ' print message error group cannot be empty
                                lblMessage.Text = strErr5

                                ' set flag 
                                flag = False

                            End If

                        Else

                            ' print message error belongs to is not itself or its child
                            lblMessage.Text = strErr7

                            'set flag
                            flag = False

                        End If

                    Else

                        ' print message error belongs to cannot be empty
                        lblMessage.Text = strErr4

                        ' set flag
                        flag = False

                    End If

                Else

                    ' clear message
                    lblMessage.Text = Nothing

                End If

            Else

                ' print message level cannot be empty
                lblMessage.Text = strErr6

                'set flag
                flag = False

            End If

        Else

            ' print message name cannot be empty
            lblMessage.Text = strErr3

            ' set flag
            flag = False

            txtOrName.Focus()

        End If

        ' check if input data valid
        If flag Then

            ' create dto organization
            Dim dtoOrganization As DTOOrganization = New DTOOrganization()


            'get inputs data 
            dtoOrganization.NoProperty = txtOrNo.Text

            dtoOrganization.NameProperty = txtOrName.Text

            dtoOrganization.LevelProperty = cboOrLevel.SelectedValue

            If cboBeTo.SelectedIndex > 0 Then

                dtoOrganization.SupProperty = cboBeTo.SelectedValue.ToString()

            Else

                dtoOrganization.SupProperty = Nothing

            End If


            dtoOrganization.GroupProperty = cboGroup.SelectedValue.ToString()

            dtoOrganization.AddressProperty = txtAddress.Text

            dtoOrganization.NoteProperty = txtNote.Text

            ' add to database
            If bsOrganization.UpdateOrganization(dtoOrganization) Then

                ' print message
                lblMessage.Text = strMsg2

                ' load dtorgan and treeview
                dtOrgan = bsOrganization.GetOrganization()

                LoadTreeOrgan(dtOrgan, trvOrgan)

                trvOrgan.ExpandAll()

                ' disable all
                disableActions()

            Else

                ' print error message
                lblMessage.Text = strErr9

            End If


        End If


    End Sub

    ''' <summary>
    ''' check node is belongs to the other.
    ''' </summary>
    ''' <param name="strParentNo"></param>
    ''' <param name="strChildNo"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function isChild(ByVal strParentNo As String, ByVal strChildNo As String) As Boolean

        For Each row As DataRow In dtOrgan.Rows

            ' find the child node
            If row.Item("ORGANIZATIONAL_NO").ToString().Equals(strChildNo) Then

                ' get duoc sup cua child node chu phai kiem tra cai sup no han co nam trong cai parent ko
                If row.Item("SUP_ORGANIZATIONAL_NO").ToString().Equals(strParentNo) Then

                    Return True

                Else

                    ' check sup organization have a sup organization is str parent
                    If isChild(strParentNo, row.Item("SUP_ORGANIZATIONAL_NO").ToString()) Then

                        Return True

                    Else

                        Return False

                    End If

                End If

            End If

        Next

        Return False

    End Function


    Private Sub btnDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDelete.Click

        ' check if organization still contain employee 
        If Not bsOrganization.CheckOrganContainEmployee(txtOrNo.Text.Trim()) Then

            ' check if this organization didn't have childrent
            If trvOrgan.SelectedNode.Nodes.Count < 1 Then

                Dim dtoOrganization As DTOOrganization = New DTOOrganization()

                dtoOrganization.NoProperty = txtOrNo.Text

                If bsOrganization.DeleteOrganization(dtoOrganization) Then

                    ' print message
                    lblMessage.Text = strMsg3

                    ' load dt organ and treeview
                    dtOrgan = bsOrganization.GetOrganization()

                    LoadTreeOrgan(dtOrgan, trvOrgan)

                    trvOrgan.ExpandAll()

                    'clear & disable all
                    enableActionAdd()
                    disableActions()

                Else

                    ' print error message
                    lblMessage.Text = strErr10

                End If

            Else

                ' print message error delete child node before delete parent
                lblMessage.Text = "Delete child organization before delete parent one."

            End If

        Else

            lblMessage.Text = "Cannot delete organization. It still contains employee."

        End If
        
    End Sub


    ''' <summary>
    ''' Check organization child must have same group as parent.
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function CheckGroup(ByVal strCGroup As String, ByVal strSupNo As String) As Boolean

        For Each row As DataRow In dtOrgan.Rows

            If row.Item("ORGANIZATIONAL_NO").ToString().Equals(strSupNo) Then

                If Not String.IsNullOrEmpty(row.Item("GROUP_ID").ToString()) Then

                    If row.Item("GROUP_ID").ToString().Equals(strCGroup) Then

                        Return True

                    Else

                        Return False

                    End If

                Else

                    Return True

                End If

            End If

        Next

    End Function

End Class